package common

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
	"os"
)

func NewZapLogger(logLevel string, logFilePath string) *zap.Logger {

	// 日志级别
	atomicLevel := zap.NewAtomicLevel()
	switch logLevel {
	case "DEBUG":
		atomicLevel.SetLevel(zapcore.DebugLevel)
	case "INFO":
		atomicLevel.SetLevel(zapcore.InfoLevel)
	default:
		atomicLevel.SetLevel(zapcore.InfoLevel)
	}

	// 设置默认字段
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "time", // 时间字段
		LevelKey:       "level",
		NameKey:        "name",
		CallerKey:      "line",                                                 // 调用者
		MessageKey:     "msg",                                                  // 内容
		FunctionKey:    "func",                                                 // 函数名
		StacktraceKey:  "stacktrace",                                           // 堆栈
		LineEnding:     zapcore.DefaultLineEnding,                              // 换行字符
		EncodeLevel:    zapcore.LowercaseLevelEncoder,                          // 小写
		EncodeTime:     zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"), // 时间格式
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.FullCallerEncoder,
		EncodeName:     zapcore.FullNameEncoder,
	}

	// 打印控制台用的Core
	zapCoreConsole := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(os.Stdout),
		atomicLevel,
	)

	// 日志轮转: lumberjack 实现
	writer := &lumberjack.Logger{
		// 日志名称
		Filename: logFilePath,
		// 日志大小限制，单位MB
		MaxSize: 1,
		// 历史日志文件保留天数
		MaxAge: 30,
		// 最大保留历史日志数量
		MaxBackups: 2,
		// 本地时区
		LocalTime: true,
		// 历史日志文件压缩标识
		Compress: false,
	}

	// 写文件用的CoreFile
	zapCoreFile := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(writer),
		atomicLevel,
	)

	// 这里实现控制台和文件一起输出
	core := zapcore.NewTee(
		zapCoreFile,
		zapCoreConsole,
	)

	return zap.New(core, zap.AddCaller())
}
